import { createRole, deleteRole, getRoleList, getRoleRecord, updateRole } from "@/api/role";
import { formatFormItem, FormItemType, FormTableItemType } from "@/components/FormByData/FormByData";
import Table, { TableRef } from "@/components/Table";
import { Card, Space, Button, message, FormInstance, TreeDataNode, Tree } from "antd";
import { Key, MutableRefObject, useCallback, useRef, useState } from "react";
import { Operation } from "@/typings/common";
import { formatDate } from "@/utils/date";
import { EditOutlined, AuditOutlined } from "@ant-design/icons";
import FormByData from "@/components/FormByData/FormByData";
import { CreateRoleReq, Role as RoleType, UpdateRoleReq } from "@/typings/api/role";
import Search from "@/components/Search";
import Modal from "@/components/Modal/Modal";
import DictionaryColumnRender from "@/components/DictionaryColumnRender";
import { getPermissionList } from "@/api/permission";
import { Permission } from "@/typings/api/permission";
import styles from "./Role.module.scss";
import { useRoute } from "@/hooks/useRoute";

type SearchFields = Pick<RoleType, "name" | "key">;

const Role = () => {
    const columns: FormTableItemType<UpdateRoleReq>[] = [
        { dataIndex: "name", title: "角色名", required: true },
        {
            dataIndex: "status",
            title: "角色状态",
            dictType: "status",
            dictClass: "boolean",
            render: value => <DictionaryColumnRender dictType="status" value={value} />,
            type: "select",
        },
        { dataIndex: "permissions", title: "权限", isForm: false, isTable: false },
        { dataIndex: "desc", title: "描述" },
        { dataIndex: "key", title: "角色标识", required: true },
        { dataIndex: "createdAt", title: "创建时间", render: val => formatDate(val), isForm: false },
        { dataIndex: "updatedAt", title: "更新时间", render: val => formatDate(val), isForm: false },
        { dataIndex: "operation", isForm: false, title: "操作", fixed: "right" },
    ];

    const [formModalShow, setFormModalShow] = useState(false);
    const [opType, setOpType] = useState<Operation>("add");
    const currentRecord = useRef<UpdateRoleReq>();

    const handleAdd = () => {
        setOpType("add");
        setFormModalShow(true);
        formRef.current?.resetFields();
    };

    const clickEdit = (record: UpdateRoleReq) => {
        setOpType("edit");
        setFormModalShow(true);
        formRef.current?.resetFields();
        setTimeout(() => {
            formRef.current?.setFieldsValue(record);
        });
        currentRecord.current = record;
    };

    const tableRef = useRef<TableRef>(null);
    const formRef: MutableRefObject<FormInstance<UpdateRoleReq> | null> = useRef(null);
    const submit = async () => {
        const formData = await formRef.current?.validateFields?.();
        if (!formData) return;
        if (opType === "add") {
            await createRole(formData as CreateRoleReq);
            message.success("创建成功");
        } else {
            if (!currentRecord.current) return;
            await updateRole({ ...formData, _id: currentRecord.current._id });
            message.success("编辑成功");
        }
        tableRef.current?.getList();
        setFormModalShow(false);
    };

    const searchFormItems: FormItemType[] = [
        { label: "角色名", name: "name" },
        { label: "角色标识", name: "key" },
    ];
    const searchParams = useRef<Partial<RoleType>>({});
    const handleSearch = async (formData: SearchFields) => {
        searchParams.current = formData;
        await tableRef.current?.getList(1, 10);
    };

    const searchFromRef = useRef<FormInstance>();
    const handleReset = () => {
        searchFromRef.current?.resetFields();
        searchParams.current = {};
        tableRef.current?.getList(1, 10);
    };

    const [authModalShow, setAuthModalShow] = useState(false);
    const [checkedKeys, setCheckedKeys] = useState<Key[]>([]);
    const [treeData, setTreeData] = useState<TreeDataNode[]>([]);
    const clickAuth = async (record: UpdateRoleReq) => {
        const treeData = await getTreeData();
        currentRecord.current = record;
        setAuthModalShow(true);
        const { data } = await getRoleRecord(record._id);
        const rolePermissionsIds = data.permissions.map((item: Permission) => item._id);
        const keys: Key[] = [];
        // 检查当前节点是否拥有所有子节点的权限
        const hasAllChildrenPermissions = (children: TreeDataNode[]): boolean => {
            return children.every(child => {
                // 如果有子节点，递归检查子节点是否拥有所有权限
                if (child.children?.length) return hasAllChildrenPermissions(child.children);
                // 如果是叶子节点，检查是否在 rolePermissionsIds 中
                return rolePermissionsIds.includes(child.key);
            });
        };
        const loop = (list: TreeDataNode[]) => {
            list.forEach(item => {
                if (item.children?.length && hasAllChildrenPermissions(item.children)) keys.push(item.key);
                if (!item.children?.length && rolePermissionsIds.includes(item.key)) keys.push(item.key);
                loop(item.children || []);
            });
        };
        loop(treeData);
        setCheckedKeys(keys);
    };

    const routeHandle = useRoute();
    const accredit = useCallback(async () => {
        await updateRole({ _id: currentRecord.current!._id, permissions: checkedKeys });
        message.success("授权成功");
        setAuthModalShow(false);
        tableRef.current?.getList();
        routeHandle.fetch();
    }, [checkedKeys]);
    const [expandedKeys, setExpandedKeys] = useState<Key[]>([]);
    const getTreeData = async () => {
        // prettier-ignore
        const { data } = await getPermissionList();
        let keys: Key[] = [];
        const loop = (list: Permission[]): TreeDataNode[] => {
            return list.map(item => {
                if (item.children?.length) keys.push(item._id);
                return {
                    title: item.name,
                    key: item._id,
                    children: loop((item.children || []) as Permission[]),
                    isLeaf: !item.children?.length,
                };
            });
        };
        const res = loop(data);
        setTreeData(res);
        setExpandedKeys(keys);
        return res;
    };
    const [authModalHeight, setAuthModalHeight] = useState("500px");
    return (
        <Card
            title={
                <Search<SearchFields>
                    title="角色管理"
                    formItems={searchFormItems}
                    onReset={handleReset}
                    onAdd={handleAdd}
                    onSearch={handleSearch}
                    getFormRef={ref => (searchFromRef.current = ref)}
                    createPermission="/system/role/create"
                    listPermission="/system/role/list"
                />
            }
        >
            <Table<UpdateRoleReq>
                ref={tableRef}
                columns={columns}
                getApi={p => getRoleList({ ...p, ...searchParams.current })}
                delApi={deleteRole}
                actionMore={record => (
                    <Space>
                        <Button type="primary" size="small" icon={<EditOutlined />} onClick={() => clickEdit(record)}>
                            编辑
                        </Button>
                        {record.key !== "admin" && (
                            <Button type="primary" size="small" icon={<AuditOutlined />} onClick={() => clickAuth(record)}>
                                授权
                            </Button>
                        )}
                    </Space>
                )}
                updatePermission="/system/role/update"
                deletePermission="/system/role/delete"
            />

            <Modal title={opType === "add" ? "添加" : "编辑"} open={formModalShow} onCancel={() => setFormModalShow(false)} onOk={submit} forceRender>
                <FormByData
                    getFormRef={ref => (formRef.current = ref)}
                    formItems={formatFormItem(columns)}
                    cols={1}
                    formProps={{ initialValues: { status: true } }}
                />
            </Modal>

            <Modal
                title="授权"
                width={900}
                open={authModalShow}
                onCancel={() => setAuthModalShow(false)}
                onOk={accredit}
                forceRender
                style={{ display: "flex", justifyContent: "center" }}
                onFullChange={isFull => setAuthModalHeight(isFull ? "calc(100vh - 124px)" : "500px")}
            >
                <div className={`${styles.treeWrap} no-scrollbar`}>
                    <Tree.DirectoryTree
                        checkable
                        showIcon
                        treeData={treeData}
                        style={{ minWidth: 250, height: authModalHeight }}
                        expandedKeys={expandedKeys}
                        autoExpandParent
                        onExpand={keys => setExpandedKeys(keys)}
                        checkedKeys={checkedKeys}
                        onCheck={keys => setCheckedKeys(keys as Key[])}
                    />
                </div>
            </Modal>
        </Card>
    );
};

export default Role;
